from datetime import datetime
from django.db import models
import random, requests as rq, string
from thread_lfanke import Thread


# 筛选器们
class not_complete(models.Manager):  # 筛选未完成的任务
    def get_queryset(self):
        return super().get_queryset().filter(is_complete=False)


# 筛选是学生的用户，而不是其他管理
class is_include(models.Manager):
    def get_queryset(self):
        return super().get_queryset().filter(include=True)


# 众表
class user(models.Model):
    name = models.CharField(max_length=31)
    q_number = models.CharField(max_length=20, unique=True)
    class_number = models.IntegerField()
    id_number = models.CharField(max_length=10, unique=True)
    is_root = models.BooleanField(default=False)
    include = models.BooleanField(default=True)  # 以防日后不是同学的人发通知

    objects = is_include()


class QingJia(models.Model):
    q_number = models.CharField(max_length=20)
    info = models.CharField(max_length=300, verbose_name='请假理由')
    time = models.DateTimeField(auto_now_add=True, verbose_name='发起请假的时间')
    jieci = models.CharField(max_length=20, verbose_name='请假的节次')
    is_qingjia = models.BooleanField(default=False, verbose_name='是请假，否的话是调换')
    tiaohuan = models.CharField(max_length=20, null=True, verbose_name='调换至')


class task(models.Model):
    name = models.CharField(max_length=120, unique=True)  # name为储存位置
    begin = models.DateTimeField()
    end = models.DateTimeField()
    send_to = models.CharField(max_length=120, null=True)  # 发哪儿，默认邮箱在base配置
    method = models.CharField(max_length=21, null=True)  # 提交方式，默认email
    is_complete = models.BooleanField(default=False)  # 超时或手动提交
    re_name = models.CharField(null=True, max_length=50)
    pattern = models.CharField(null=True, max_length=240)  # 命名模板
    describe = models.CharField(null=True, max_length=999)  # 任务描述
    type_of_content = models.CharField(null=True, max_length=21)  # 任务要求的提交类型，file、image、images

    tip_grade = models.SmallIntegerField(default=9)  # 提醒等级

    objects_all = models.Manager()
    objects = not_complete()
    creater = models.ForeignKey(to='user', null=True, to_field='q_number', on_delete=models.CASCADE)  # 谁创建的


class collecte(models.Model):
    id_number = models.CharField(max_length=31)
    q_number = models.ForeignKey(to='user', to_field='q_number', on_delete=models.CASCADE)
    img_path = models.CharField(max_length=400)  # 多的用,分割
    task = models.ForeignKey(to='task', to_field='name', on_delete=models.CASCADE)


class store(models.Model):  # 将挂起的任务放入仓库备用，如果删除则彻底删除，不放入仓库
    # 备份库就用pd，导入也是
    task = models.CharField(max_length=51)
    table_path = models.CharField(max_length=291)


class tip(models.Model):  # 负责定时提醒，有状态码，标注一段时间提醒还是长时间提醒
    """
    开始时间：，，，结束时间(null为无限)，，，提醒时间，，，周期，，，周期持续几次，，，方式，，，文本内容，，，图片内容
    """
    name = models.CharField(max_length=33, unique=True)  # 提醒名字，作为标题（伪）
    begin = models.DateTimeField()  # 什么时候提醒
    end = models.DateTimeField(null=True)  # 空为永久任务
    time_delta = models.TimeField(null=True)  # 提醒大周期，在提醒时间上累加，无为一次任务
    sub_delta = models.TimeField(null=True)  # 小周期，，，无为没有
    time_time = models.IntegerField(default=0)  # 小周期持续几次，，，0为没有
    tips = models.CharField(max_length=999, null=True)  # 提醒什么
    images = models.CharField(max_length=666, null=True)  # 图片路径，英文逗号分割
    method = models.IntegerField(default=0)  # 提醒方式，0为私发，1为@all，2为两个都要


class statistic_event(models.Model):  # 报数事件，报冒号后的所有东西
    name = models.CharField(max_length=996, unique=True)
    q_number = models.ForeignKey(to='user', to_field='q_number', on_delete=models.CASCADE)
    time = models.DateTimeField(auto_now=True)


class statistics_event_collecte(models.Model):  # 收集消息
    event = models.ForeignKey(to='statistic_event', to_field='name', on_delete=models.CASCADE)
    q_number = models.ForeignKey(to='user', to_field='q_number', on_delete=models.CASCADE)
    info = models.CharField(max_length=886)


class cache(models.Model):
    q_number = models.ForeignKey(to='user', to_field='q_number', on_delete=models.CASCADE)
    event = models.CharField(max_length=300)  # recv_file或wait_file_任务名字  或  wait_img_任务名字
    time = models.DateTimeField(auto_now_add=True)
    status = models.IntegerField(default=0)  # 状态，1为文件，0为文本
    other = models.CharField(max_length=300, null=True)  # url&name或文本

    @classmethod
    def push(cls, q_number, event, status=0, other=None):  # 1为已有任务占用，0为成功
        temp = cls.objects.filter(q_number=q_number)
        if temp.first():  # 先将基本功能实现，以后再建立缓存文件区
            return {'status': 1, 'info': {'time': temp.first().time, 'event': temp.first().event}}
        temp.create(q_number_id=q_number, event=event, status=status, other=other)
        return {'status': 0}

    @classmethod
    def remove(cls, q_number):
        cls.objects.filter(q_number_id=q_number).delete()
        return {'status': 0}

    @classmethod
    def get(cls, q_number):
        temp = cls.objects.filter(q_number_id=q_number)
        return {'status': 0, 'qrset': temp,
                'task': ('等待[' + temp.first().event.split('_')[-1] + ']任务文件上传'
                         ) if temp.first().event != 'recv_file' else '等待输入将文件上传至哪个任务，即：[提交任务：任务名称]'} \
            if temp.first() else {'status': 404}


class KeyManager(models.Manager):

    def get_queryset(self):
        return super().get_queryset().filter(done=False)


class Key(models.Model):
    name = models.CharField(max_length=100, verbose_name="名字")
    msg = models.CharField(max_length=3000, null=True, verbose_name="描述")
    done = models.BooleanField(default=False, verbose_name="看了没")
    time = models.DateTimeField(auto_now_add=True)
    evaluate = models.CharField(max_length=3000, null=True, verbose_name="看之后的追加内容")

    objects_all = models.Manager()
    objects = KeyManager()


class FundSource(models.Model):
    """资金来源"""
    name = models.CharField(max_length=100, unique=True)


class MoneyStore(models.Model):
    """花费记录"""
    name = models.CharField(max_length=100, verbose_name='在哪？得的/花的')
    change = models.FloatField(default=0, verbose_name='变动金额')
    source_id = models.IntegerField('FundSource主键')
    time = models.DateTimeField(auto_now_add=True)


import json, os
dir_name = 'DaBai_v1'
default_info = json.load(open('.' + os.sep + dir_name + os.sep + 'baseinfo.json'))
rootdir = '.' + os.sep + dir_name
temp_file_dir = rootdir + os.sep + default_info['tempfiledir']


class TempFile(models.Model):
    """临时文件储存，为了避免名字一样，所以将名字和path分开"""
    name = models.CharField(max_length=100)
    path = models.CharField(max_length=1000)  # 6位随机数字/字母+n位拓展名，用英文;分割不同文件
    time = models.DateTimeField(auto_now_add=True)
    evaluate = models.CharField(max_length=1000, null=True)

    @classmethod
    def get_files_from_web(cls, files: list[str], addresses: str=None) -> str:
        """爬取文件，返回文件储存的地址（拼接好的）"""
        res = []
        for file in files:
            random_filename = ''.join(random.sample(string.ascii_letters+string.digits, 6))
            with open(f'{temp_file_dir}{os.sep}{random_filename}{f".{addresses}" if addresses else ""}', 'wb') as f:
                f.write(rq.get(file).content)
            res.append(random_filename)
        return ';'.join(res)


    @classmethod
    def async_dump_files(cls, files: list[str], name, addresses: str=None, evaluate=None, func_end=None, **kw):
        """将这些文件储存后保存temp file"""
        def temp():
            res = cls.get_files_from_web(files)
            cls.objects.create(name=name, path=res, evaluate=evaluate)
            if func_end:
                func_end(**kw)
        Thread(func=temp).start()
